﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using SteamWebAPI;
using DotabuffWebAPI;
using Dota2WebAPI;
using System.Threading;
using System.Windows.Threading;
using System.IO;
using System.Windows.Media.Animation;
using System.Collections.ObjectModel;
using System.Xml.Serialization;
using System.Xml;
using System.Speech.Synthesis;
using System.Diagnostics;
using System.Reflection;
using System.Net;

namespace Stack_Check
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        public enum Status  {Scanning, Waiting, WatcherRunning, WatcherIdle};


        private Status applicationStatus = Status.Waiting;

        private string folderPath = "Unknown";

        private KeyboardHook startHook;
        private KeyboardHook infoHook;

        private int timer = 600;


        private Thread scanner;
        private GamelogWatcher watcher;

        private ObservableCollection<GameSession> history = new ObservableCollection<GameSession>();

        private System.Timers.Timer roshanTimer;

        public MainWindow()
        {
            InitializeComponent();

            Server server = new Server("F12E71BAE29489AF6EBCC29F75865E11");

            LoadSettings();

            //Version updaterVersion = AssemblyName.GetAssemblyName("Updater.exe").Version;
            
            /*
            if (updaterVersion.Major < 2)
            {
                // Je nutná aktualizace updateru
                MessageBoxResult result = MessageBox.Show("Je nutné provést aktualizaci programu, přejete si pokračovat?", "Aktualizace", MessageBoxButton.YesNoCancel, MessageBoxImage.Information);
                switch (result)
                {
                    case MessageBoxResult.No:
                        this.Close();
                        break;
                    case MessageBoxResult.Yes:
                        Process[] processes = Process.GetProcessesByName("Updater");
                        if (processes.Length != 0)
                        {
                            processes[0].Kill();
                        }
                        using (WebClient myWebClient = new WebClient())
                        {
                            try
                            {
                                string myStringWebResource = "http://www.stud.fit.vutbr.cz/~xvalaj01/SC/Updater.exe";
                                string filename = "Updater.exe";
                                myWebClient.DownloadFile(myStringWebResource, filename);
                            }
                            catch (SystemException exception)
                            {
                                MessageBox.Show(exception.Message);
                            }

                        }
                        break;
                    default:
                        break;
                }
            }
             */
            //Testovací načtení historie
            LoadHistory();


            SetupHooks();

            labelPlayername.MouseUp += labelPlayername_MouseUp;
        }



        void labelPlayername_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (user != null)
            {
                string url = "http://dotabuff.com/search?q=" + user.SteamID;
                System.Diagnostics.Process.Start(url);
            }

        }

        private void SetupHooks()
        {
            startHook = new KeyboardHook(this, System.Windows.Forms.Keys.F7, ModifierKeys.None);
            startHook.HotkeyPressed += startHook_HotkeyPressed;

            infoHook = new KeyboardHook(this, System.Windows.Forms.Keys.F8, ModifierKeys.None);
            infoHook.HotkeyPressed += infoHook_HotkeyPressed;
        }

        void infoHook_HotkeyPressed(object sender, EventArgs e)
        {
            SpeechSynthesizer synthesizer = new SpeechSynthesizer();
            string line = timer / 60 + ":" + timer % 60 + " remaining";
            synthesizer.SpeakAsync(line);
        }



        public void LoadSettings()
        {

            try
            {
                XmlSerializer serialiser = new XmlSerializer(typeof(string));
                XmlTextReader reader = new XmlTextReader("settings.xml");
                string result = null;
                result = (string)serialiser.Deserialize(reader);
                folderPath = result;
            }
            catch (InvalidOperationException e)
            {
                
            }
        }

        public void SaveSettings()
        {

            XmlSerializer serialiser = new XmlSerializer(typeof(string));
            XmlTextWriter writer = new XmlTextWriter("settings.xml", System.Text.Encoding.UTF8);
            try
            {

                writer.Formatting = Formatting.Indented;
                serialiser.Serialize(writer, folderPath);
            }
            catch (SystemException systemException)
            {
                MessageBox.Show(systemException.ToString());
            }
            finally
            {
                writer.Close();
            }
           
        }

        private void dataContent(SteamUser user)
        {
            // Netuším k čemu to bylo
        }

        private SteamUser user = null;

        private void selectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                //SteamUser user = null;
                if (e.AddedItems.Count == 0)
                {
                    return;
                }
                // Jméno
                PlayerListItem item = (PlayerListItem)e.AddedItems[0];
                user = item.User;
                labelPlayername.Content = user.Name;

                //Pravé jméno
                labelRealName.Content = user.RealName;

                // Avatar
                BitmapImage bitmap = new BitmapImage();
                bitmap.BeginInit();
                bitmap.UriSource = user.Avatar;
                bitmap.EndInit();
                imageAvatar.Source = bitmap;

                //Wins
                LabelWins.Content = user.Info.Wins;
                LabelLost.Content = user.Info.Loss;
                string label = user.Info.Winrate.ToString("P2");
                LabelWinrate.Content = label;
                if (user.Info.Winrate > 0.5)
                {
                    LabelWinrate.Foreground = Brushes.Green;
                }
                else
                {
                    LabelWinrate.Foreground = Brushes.Red;
                }

                //Country Flag
                labelCountryTag.Content = user.CountryTag;
                
                //http://cdn.steamcommunity.com/public/images/countryflags/cz.gif
                string uri = "http://cdn.steamcommunity.com/public/images/countryflags/";
                uri += user.CountryTag.ToLower();
                uri += ".gif";
                Uri flagUri = new Uri(uri);
                BitmapImage flag = new BitmapImage();
                flag.BeginInit();
                flag.UriSource = flagUri;
                flag.EndInit();
                imageCountryFlag.Source = flag;

                
            }
            catch (SystemException systemException)
            {
                MessageBox.Show(systemException.Message);
            }
        }

        private GameSession activeSession;

        private void startScan()
        {
            try
            {


                progressBar.Value = progressBar.Minimum;
                string data = System.Windows.Clipboard.GetText();
                userList.Items.Clear();
                activeSession = new GameSession(data);
                progressBar.Value = 7;
                // Tato mrcha trvá rok
                activeSession.Resolved += activeSession_Resolved;
                activeSession.Changed += activeSession_Changed;
                progressText.Text ="Scanning...";
                scanner = new Thread(new ThreadStart(activeSession.Resolve));
                scanner.Start();
            }
            catch (SystemException systemException)
            {
                MessageBox.Show(systemException.Message);
            }
        }

        private void stopScan()
        {
            try
            {
                scanner.Abort();
            }
            catch (SystemException systemException)
            {
                MessageBox.Show(systemException.Message);
            }
        }

        private void startWatcher()
        {
            watcher = new GamelogWatcher(folderPath);
            watcher.DestinationChanged += watcher_DestinationChanged;
            if (watcher != null)
                watcher.Start();
        }

        private void stopWatcher()
        {
            if (watcher != null)
            {
                watcher.Abort();
                watcher.DestinationChanged -= watcher_DestinationChanged;
            }
                
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            try
            {
                switch (applicationStatus)
                {
                    // zahájí se Scan
                    case Status.Waiting:
                        applicationStatus = Status.Scanning;
                        startScan();
                        buttonScan.Content = "Stop";
                        break;
                    
                    // Ukončí se scan
                    case Status.Scanning:
                        applicationStatus = Status.Waiting;
                        stopScan();
                        buttonScan.Content = "Scan";
                        break;
                    
                    // Watcher je nastaven ale nespuštěn
                    case Status.WatcherIdle:
                        applicationStatus = Status.WatcherRunning;
                        startWatcher();
                        buttonScan.Content = "Stop watcher";
                        break;

                    // Watcher je nastaven a spuštěn.
                    case Status.WatcherRunning:
                        applicationStatus = Status.WatcherIdle;
                        stopWatcher();
                        buttonScan.Content = "Start watcher";
                        break;
                }
               


            }
            catch (SystemException systemException)
            {
                MessageBox.Show(systemException.Message);
            }
            

        }

        void activeSession_Changed(object sender, SteamWebAPI.SessionChangedEventArgs e)
        {

            this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
            {
                try
                {
                    progressText.Text = e.Operation;

                    progressBar.Value += e.Value;
                    Duration duration = new Duration(TimeSpan.FromSeconds(0.5));
                    DoubleAnimation da2 = new DoubleAnimation(progressBar.Value, progressBar.Value + e.Value, duration);
                    DoubleAnimation doubleanimation = new DoubleAnimation(100, duration);
                    DoubleAnimation da = new DoubleAnimation(progressBar.Value, duration);
                    progressBar.BeginAnimation(ProgressBar.ValueProperty, da2);
                }
                catch (SystemException systemException)
                {
                    MessageBox.Show(systemException.Message);
                }
                //
            });
        }


        void activeSession_Resolved(object sender, EventArgs e)
        {
            
          this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
            {
                try
                {
                    // Kontrola kdy ti lidi hráli naposledy
                    foreach (SteamUser user in activeSession.Players)
                    {
                        if (history != null)
                        {

                            /*
                            foreach (var game in history)
                            {
                                DateTime? result = game.FindUser(user);
                                if (result != null)
                                    user.LastTimePlayed.Add(result.Value);   
                            }
                             */
                            
                            Parallel.ForEach(history, game =>
                            {
                                DateTime? result = game.FindUser(user);
                                if (result != null)
                                    user.LastTimePlayed.Add(result.Value);
                            });
                             
                        }

                    }


                    history.Add(activeSession);
                    progressText.Text = "Idle...";
                    progressBar.BeginAnimation(ProgressBar.ValueProperty, null);
                    buttonScan.Content = "Scan";
                    applicationStatus = Status.Waiting;
                    foreach (SteamUser player in activeSession.Players)
                    {
                        userList.Items.Add(new PlayerListItem(player));
                    }

                    
                    //Play sound
                    soundAlarm();
                    SaveHistory();

                }
                catch (SystemException systemException)
                {
                    MessageBox.Show(systemException.ToString());
                }
            });
        }

        private void soundAlarm()
        {
            try
            {
                System.Media.SoundPlayer player = new System.Media.SoundPlayer(@"timeout.wav");
                player.Play();
            }
            catch (Exception e)
            {
                throw;
            }
        }

        private void Generate()
        {
        }

        private void buttonSelectFolder_MouseEnter(object sender, MouseEventArgs e)
        {
            buttonSelectFolder.ToolTip = folderPath;
        }

        private void buttonSelectFolder_MouseLeave(object sender, MouseEventArgs e)
        {
            
        }

        private void checkBoxAutoScan_Checked(object sender, RoutedEventArgs e)
        {
            if (scanner != null && scanner.IsAlive)
                scanner.Abort();
            applicationStatus = Status.WatcherIdle;
            buttonScan.Content = "Start watcher";
        }

        private void checkBoxAutoScan_Unchecked(object sender, RoutedEventArgs e)
        {
            if (watcher != null && watcher.isAlive)
                watcher.Abort();
            applicationStatus = Status.Waiting;
            buttonScan.Content = "Scan";
        }

        private void buttonSelectFolder_Click(object sender, RoutedEventArgs e)
        {
            var dialog = new System.Windows.Forms.FolderBrowserDialog();
            System.Windows.Forms.DialogResult result = dialog.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK)
            {
                folderPath = dialog.SelectedPath;
                SaveSettings();
            }
        }

        private void soundStart()
        {
            try
            {
                System.Media.SoundPlayer player = new System.Media.SoundPlayer(@"start.wav");
                player.Play();
            }
            catch (Exception e)
            {
                throw;
            }
        }

        void watcher_DestinationChanged(object sender, System.IO.FileSystemEventArgs e)
        {

            try
            {
               
                this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
                {
                    using (StreamReader reader = new StreamReader(e.FullPath))
                    {
                        soundStart();
                        string data = reader.ReadToEnd();
                        reader.Close();
                        System.Windows.Clipboard.SetText(data);
                        startScan();
                    }
                });

            }
            catch (SystemException systemException)
            {
                MessageBox.Show(systemException.Message);
            }
        }

        private void expanderHistory_Expanded(object sender, RoutedEventArgs e)
        {
            displayHistory();
        }

        private void displayHistory()
        {
            historyList.Items.Clear();
            foreach (GameSession session in history)
            {
                HistoryListItem item = new HistoryListItem(session);
                item.ItemDeleted += item_ItemDeleted;
                historyList.Items.Add(item);
            }
        }

        void item_ItemDeleted(object sender, ItemDeletedEventArgs args)
        {
            bool result = history.Remove(args.Session);
            SaveHistory();
            displayHistory();
        }

        private void historyList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            
            try
            {
                if (e.AddedItems.Count == 0)
                    return;
                HistoryListItem historyItem = (HistoryListItem)e.AddedItems[0];
                this.activeSession = historyItem.Session;

                expanderHistory.IsExpanded = false;
                userList.Items.Clear();
                userList.Focus();
                foreach (SteamUser user in activeSession.Players)
                {
                    userList.Items.Add(new PlayerListItem(user));
                }
            }
            catch(SystemException systemException)
            {
                MessageBox.Show(systemException.Message);
            }
             
        }

        private void buttonTimerSettings_Click(object sender, RoutedEventArgs e)
        {
            SettingsWindow window = new SettingsWindow();
            bool? result = window.ShowDialog();
            // Testovací blok
            if (!result.Value)
            {
                SpeechSynthesizer synthetizer = new SpeechSynthesizer();
                synthetizer.SpeakAsync("What are you? Some sort of homophobe?");
            }
            // Testovací blok
        }

        private void buttonStartTimer_Click(object sender, RoutedEventArgs e)
        {
            if (roshanTimer != null && roshanTimer.Enabled)
                roshanTimer.Dispose();

            timer = 600;
            roshanTimer = new System.Timers.Timer(1000);
            roshanTimer.Start();
            roshanTimer.Elapsed += roshanTimer_Elapsed;
        }

        void startHook_HotkeyPressed(object sender, EventArgs e)
        {
            if (roshanTimer != null && roshanTimer.Enabled)
                roshanTimer.Dispose();

            timer = 600;
            roshanTimer = new System.Timers.Timer(1000);
            roshanTimer.Elapsed += roshanTimer_Elapsed;
            roshanTimer.Start();
            

            SpeechSynthesizer synthesizer = new SpeechSynthesizer();
            synthesizer.SpeakAsync("Timer started, Roshaan is up in 10 minutes.");
        }

        void roshanTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
            {
                timer--;
                if (timer < 0)
                {
                    roshanTimer.Dispose();
                    timer = 600;
                }

                if (timer == 300)
                {
                    SpeechSynthesizer synthesizer = new SpeechSynthesizer();
                    synthesizer.SpeakAsync("Aegis is down in one minute.");
                    // Aegis down in one minute
                }
                if (timer == 240)
                {
                    SpeechSynthesizer synthesizer = new SpeechSynthesizer();
                    synthesizer.SpeakAsync("Aegis is down, roshaan is up in 4 minutes.");
                    // Aegis down
                }
                if (timer == 120)
                {
                    // Roshan up in 2 minutes
                    SpeechSynthesizer synthesizer = new SpeechSynthesizer();
                    synthesizer.SpeakAsync("Roshaan is up in two minutes.");
                }
                if (timer == 60)
                {
                    // Roshan up in 1 minute
                    SpeechSynthesizer synthesizer = new SpeechSynthesizer();
                    synthesizer.SpeakAsync("Roshaan is up in one minute.");
                }
                if (timer == 30)
                {
                    // Roshan up in 30s
                    SpeechSynthesizer synthesizer = new SpeechSynthesizer();
                    synthesizer.SpeakAsync("Roshaan is up in 30 seconds.");
                }
                if (timer == 0)
                {
                    // Roshan is up
                    SpeechSynthesizer synthesizer = new SpeechSynthesizer();
                    synthesizer.SpeakAsync("Roshaan is up.");
                }

                labelRoshanTimer.Content = timer / 60 + ":" + (((timer % 60) < 10) ? "0" : "") + timer % 60;
            });
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            if (roshanTimer != null)
                roshanTimer.Dispose();
        }

        private void LoadHistory()
        {
            try
            {
                XmlSerializer s = new XmlSerializer(typeof(ObservableCollection<GameSession>));
                XmlTextReader reader = new XmlTextReader("history.d2s");
                ObservableCollection<GameSession> result = null;
                result = (ObservableCollection<GameSession>)s.Deserialize(reader);
                history = result;
            }
            catch (SystemException e)
            {
                MessageBox.Show("Nepodařilo se načíst soubor s historií her.","Upozornění",MessageBoxButton.OK,MessageBoxImage.Exclamation);
            }
        }

        private void SaveHistory()
        {
            try
            {
                XmlSerializer serialiser = new XmlSerializer(typeof(ObservableCollection<GameSession>));
                XmlTextWriter writer = new XmlTextWriter("history.d2s", System.Text.Encoding.UTF8);
                writer.Formatting = Formatting.Indented;
                serialiser.Serialize(writer, history);
                writer.Close();
            }
            catch
            {
                MessageBox.Show("Při zápisu do souboru s historií her došlo k chybě", "Chyba!", MessageBoxButton.OK,MessageBoxImage.Error);
            }
        }

        private void buttonUpdate_Click(object sender, RoutedEventArgs e)
        {
            // Toto je final verze, ted se to musi poustet jinak
            
            Process process = new Process();
            process.StartInfo.FileName = "Updater.exe";
            process.Start();
            
            /*
            Updater.MainWindow updater = new Updater.MainWindow();
            updater.Show();  
             */
        }
    }
}
